package com.yifeng.repo.controller.excel.web;

import com.gomcarter.frameworks.base.json.JsonData;
import com.gomcarter.frameworks.base.json.JsonError;
import com.google.common.base.Strings;
import com.yifeng.repo.base.utils.converter.JacksonHelper;
import com.yifeng.repo.controller.excel.loader.ExcelLoaderManager;
import com.yifeng.repo.controller.excel.loader.dto.DataTaskDto;
import com.yifeng.repo.controller.excel.loader.dto.DataTaskTypeEnum;
import org.springframework.http.MediaType;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Created by daibing on 2022/12/29.
 */
public class ExcelLoaderServlet extends HttpServlet {
    public static final String LIST_DATA_TASK = "/listDataTask";
    public static final String GET_DATA_TASK = "/getDataTask";
    public static final String CLEAR_DATA_TASK = "/clearDataTask";
    private final ExcelLoaderManager excelLoaderManager;

    public ExcelLoaderServlet(ExcelLoaderManager excelLoaderManager) {
        this.excelLoaderManager = excelLoaderManager;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (req.getRequestURI().endsWith(LIST_DATA_TASK)) {
            List<DataTaskDto> dataApplyDtos = excelLoaderManager.listDataTask();
            this.doWrite(resp, dataApplyDtos);
        } else if (req.getRequestURI().endsWith(GET_DATA_TASK)) {
            String requestKey = req.getParameter("requestKey");
            String type = req.getParameter("type");
            DataTaskDto dataTask = excelLoaderManager.getDataTask(requestKey, DataTaskTypeEnum.get(type));
            this.doWrite(resp, dataTask);
        } else if (req.getRequestURI().endsWith(CLEAR_DATA_TASK)) {
            String prevDays = req.getParameter("prevDays");
            int cnt = excelLoaderManager.clearDataTask(Integer.parseInt(prevDays));
            this.doWrite(resp, cnt);
        } else {
            String ip = getRemoteAddress(req);
            this.doError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "http.method_post_not_supported from " + ip);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    private void doError(HttpServletResponse resp, int code, String msg) throws IOException {
        JsonError jsonError = new JsonError(msg, code);
        resp.setStatus(code);
        resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
        resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
        resp.setHeader("Cache-Control", "no-cache");
        resp.getOutputStream().write(JacksonHelper.toJson(jsonError).getBytes(StandardCharsets.UTF_8));
    }

    private void doWrite(HttpServletResponse resp, Object obj) throws IOException {
        JsonData jsonData = new JsonData(obj);
        resp.setCharacterEncoding(StandardCharsets.UTF_8.name());
        resp.setContentType(MediaType.APPLICATION_JSON_VALUE);
        resp.setHeader("Cache-Control", "no-cache");
        resp.getOutputStream().write(JacksonHelper.toJson(jsonData).getBytes(StandardCharsets.UTF_8));
    }

    public static String getRemoteAddress(HttpServletRequest req) {
        String ip = req.getHeader("X-Forwarded-For");
        // proxy mode (slb|nginx)
        if (!Strings.isNullOrEmpty(ip)) {
            int pos = ip.indexOf(",");
            if (pos != -1) {
                return ip.substring(0, pos).trim();
            } else {
                return ip.trim();
            }
        }
        // not proxy mode
        return req.getRemoteAddr();
    }
}
